
package com.epam.android.training.day8.task2;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.concurrent.ExecutionException;

/**
 * Main activity of application which allows to calculate factorial of specified
 * number in asyncronous task.
 * 
 * @author Anton Novikau
 */
public class MainActivity extends Activity {

  private static final String TAG = MainActivity.class.getSimpleName();

  private static final int VALIDATION_DIALOG_ID = 1;

  private ProgressDialog progressDialog;

  private AsyncTask<Integer, Void, Integer> factorialTask;

  private final Handler progressHandler = new ProgressHandeler();

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    addLaunchButtonAction();
  }

  /**
   * Callback for creating dialogs that are managed (saved and restored) for you
   * by the activity.
   */
  @Override
  protected Dialog onCreateDialog(int id) {
    switch (id) {
      case VALIDATION_DIALOG_ID:
        return createValidationDialog();
      default:
        return super.onCreateDialog(id);
    }
  }

  private void addLaunchButtonAction() {
    Button launchButton = (Button) findViewById(R.id.launch_async_calc_button);
    launchButton.setOnClickListener(new View.OnClickListener() {

      @Override
      public void onClick(View v) {

        EditText sourceNumberBox = (EditText) findViewById(R.id.source_number);
        String source = sourceNumberBox.getText().toString();

        if (source != null && source.length() > 0) {
          int sourceNumber = Integer.parseInt(source);

          progressDialog = ProgressDialog.show(MainActivity.this, getText(R.string.progress_title),
              getText(R.string.progress_message), true);
          factorialTask = new AsyncFactorialCalculator(progressHandler);
          factorialTask.execute(sourceNumber);
        } else {
          showDialog(VALIDATION_DIALOG_ID);
        }
      }
    });
  }

  private Dialog createValidationDialog() {
    AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);

    dialogBuilder.setMessage(R.string.validation_message).setNeutralButton(R.string.ok_button,
        new DialogInterface.OnClickListener() {

          @Override
          public void onClick(DialogInterface dialog, int which) {
            // do nothing. just close the dialog
          }
        });

    return dialogBuilder.create();
  }

  private TextView showResultMessage() {
    TextView messageArea = (TextView) findViewById(R.id.message_area);
    try {
      Integer result = factorialTask.get();
      messageArea.setText(getString(R.string.message, result));
      messageArea.setVisibility(TextView.VISIBLE);
    } catch (InterruptedException e) {
      Log.e(TAG, "Async task is interrupted", e);
      Toast.makeText(this, R.string.async_task_error, Toast.LENGTH_SHORT);
    } catch (ExecutionException e) {
      Log.e(TAG, "Exception during async calculation", e);
      Toast.makeText(this, R.string.async_task_error, Toast.LENGTH_SHORT);
    }

    return messageArea;
  }

  /**
   * Process handeler to control the status of async task.
   * 
   * @author Anton Novikau
   */
  private class ProgressHandeler extends Handler {
    @Override
    public void handleMessage(Message msg) {
      AsyncTask.Status status = (Status) msg.obj;
      if (AsyncTask.Status.FINISHED.equals(status)) {
        progressDialog.dismiss();
        showResultMessage();
      }
    }
  }
}
